﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CNShapes;
using BobcatMultiTouch;
using BobcatUtility;
using CNUtility;
using CNNetworking;
using CNStorage;

namespace CNTestApp
{
    public partial class Form1 : Form
    {

        /// <summary>
        /// Constructor.
        /// </summary>
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Called when the form is first loaded. We set up the app here.
        /// </summary>
        private void Form1_Load(object sender, EventArgs e)
        {
            // We set the log level...
            Logger.LogLevel = Logger.Level.DEBUG;

            // We load the user-preferences...
            UserPreferences.getInstance().initialize();
            setupDefaultPreferences();

            // We intialize the MTIM...
            try
            {
                MultiTouchInputManager.getInstance().initializeFromFile(CONFIG_FILENAME);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            // We set up the DB storage.
            // Note: We do this before setting up the session to make sure that it
            //       sees all events from the session when pages are added etc.
            DBStorage.getInstance().initialize();

            // We load the most recent session (if there was one)...
            bool bLoaded = DBStorage.getInstance().loadMostRecentSession();
            if (bLoaded == false)
            {
                // There was no previous session in the DB, so we set up a 
                // default empty session...
                Session.getInstance().newSession(getActionOrigin());
                Session.getInstance().addPage(getActionOrigin());
            }

            // We show the active session in the viewer / editor control...
            ctrlSession.Session = Session.getInstance();
            ctrlSession.ActivePageBackgroundImage = Utility.getImageFromResources("lined_paper.jpg");
            ctrlSession.ThumbnailBackgroundImage = Utility.getImageFromResources("lined_paper_small.jpg");

			// We set up the page-history control...
            ctrlPageHistory.initialize();
			ctrlPageHistory.PageSelectedEvent += onPageHistoryPageSelected;
        }

        /// <summary>
        /// Called shortly before the form closes. We clean up the app here.
        /// </summary>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Form_Closing frm = new Form_Closing();
            frm.Show();

            frm.update("Closing network client", 10);
            NetworkingClient.getInstance().disconnect();

            frm.update("Closing network server", 40);
            NetworkingServer.getInstance().stopServer();

            frm.update("Closing database", 80);
            DBStorage.getInstance().close();
            MultiTouchInputManager.getInstance().saveToFile(CONFIG_FILENAME);

            frm.Close();
        }

        // Sets us default properties for the app. This will only set the properties if they
        // are not already in the preferences config file.
        private void setupDefaultPreferences()
        {
            PropertyBag properties = UserPreferences.getPropertyBag();

            // User info...
            properties.setDefaultValueString("UserInfo.FirstName", "");
            properties.setDefaultValueString("UserInfo.LastName", "");

            // Properties for the GestureHandler_DragPicture...
            properties.setDefaultValueInt("GestureHandler_DragPicture.PressAndHoldInterval", 250);

            // Networking settings...
            properties.setDefaultValueInt("Networking.Port", 9559);
            properties.setDefaultValueBool("Networking.StartServerAtStartup", false);
            properties.setDefaultValueBool("Networking.ShareAddressBook", true); // We share the details of other machines / users we know about with any other people we connect to in a drawing session.
            IList<ConnectionSettings> connectionSettings = new List<ConnectionSettings>();
            connectionSettings.Add(new ConnectionSettings{FirstName="Richard", LastName="Shepherd", HostName="localhost"});
            properties.setDefaultValueList("Networking.AddressBook", connectionSettings);

            // Pen settings...
            properties.setDefaultValueFloat("DefaultPen.Width", 3f);
            properties.setDefaultValueInt("DefaultPen.Color", Color.Blue.ToArgb());

            // Font settings...
            properties.setDefaultValueString("DefaultFont.Name", "Arial");
            properties.setDefaultValueFloat("DefaultFont.Size", 12f);
        }

		/// <summary>
		/// Called when a page is selected in the page-history control.
		/// </summary>
		private void onPageHistoryPageSelected(object sender, CNPageViewer.PageFlowControl.Args e)
		{
			// We load the session that holds the page selected.
			// To do this, we first need the session ID for the selected page...
			string strSessionID = DBStorage.getInstance().getSessionIDFromPageID(e.PageID.ToString());
			if (strSessionID == "")
			{
                return;
            }

            // We load the session (if it has changed)...
            if (Session.getInstance().ID.ToString() != strSessionID)
            {
                // The session has changed, so we load the new one...
                DBStorage.getInstance().loadSession(strSessionID);
            }
            Session.getInstance().setActivePageID(e.PageID, getActionOrigin());
        }

        /// <summary>
        /// Called when the network connect button is pressed on the toolbar.
        /// </summary>
        private void tbConnect_Click(object sender, EventArgs e)
        {
            Dialog_NetworkConnection dialog = new Dialog_NetworkConnection();
            dialog.ShowDialog();
        }

        private void tbUndo_Click(object sender, EventArgs e)
        {
            ctrlSession.undo();
        }

        private void tbRedo_Click(object sender, EventArgs e)
        {
            ctrlSession.redo();
        }

        private void tbNewSession_Click(object sender, EventArgs e)
        {
            Session.getInstance().newSession(getActionOrigin());
            Session.getInstance().addPage(getActionOrigin());
        }

        private void tbNewPage_Click(object sender, EventArgs e)
        {
            Session.getInstance().addPage(getActionOrigin());
        }

        private void tbConfig_Click(object sender, EventArgs e)
        {
            MultiTouchInputManager.getInstance().showConfigScreen();
        }

        /// <summary>
        /// We return an ActionOrigin indicating that the action was a user-action
        /// madef by the current client.
        /// </summary>
        private ActionOrigin getActionOrigin()
        {
            Guid clientID = NetworkingClient.getInstance().ClientID;
            return new ActionOrigin { OriginType = ActionOrigin.OriginTypeEnum.USER_ACTION, ClientID = clientID };
        }

        #region Private data

        // File that stores XML config about which sources are used, wiimote calibration etc...
        private const string CONFIG_FILENAME = "MultiTouchConfig.xml";

        // Log file...
        private const string LOG_FILENAME = "Log.txt";
        private LogFileLogger m_Logger = new LogFileLogger(LOG_FILENAME);

        #endregion



    }
}
